package main

import (
	"epg-mc/config"
	"flag"
	"html/template"
	"io"
	"log"
	"time"

	"epg-mc/database"
	"epg-mc/database/table"
	"epg-mc/handle"
	"epg-mc/handle/api"
	"epg-mc/handle/logs"
	"epg-mc/handle/setting"
	"epg-mc/handle/stats"
	"epg-mc/middleware/jmauth"

	session "github.com/ipfans/echo-session"
	"github.com/labstack/echo"
	"github.com/labstack/echo/engine/standard"
	"github.com/labstack/echo/middleware"
)

func main() {
	flag.Parse()
	// l := logrus.New()
	table.AutoMigrate(database.ORM)
	engine := initEngine()
	// engine.SetLogger(l)
	log.Println(engine.Run(standard.New(config.Conf.Listen)))
}

var timeFunc = func(ts int64) string {
	return time.Unix(ts, 0).Format("2006-01-02 03:04:05 PM")
}

type Template struct {
	glob string
	tpl  *template.Template
}

func newTemplate(glob string) *Template {
	tpl := template.Must(template.New("").Funcs(template.FuncMap{"timeFormat": timeFunc}).ParseGlob(glob))
	return &Template{
		glob: glob, tpl: tpl,
	}
}

func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
	if config.Conf.Debug {
		t.tpl = template.Must(template.New("").Funcs(template.FuncMap{"timeFormat": timeFunc}).ParseGlob(t.glob))
	}
	return t.tpl.ExecuteTemplate(w, name, data)
}

func initEngine() *echo.Echo {
	eng := echo.New()

	// Debug mode
	if config.Conf.Debug {
		eng.SetDebug(true)
	}

	//middleware
	conf := middleware.DefaultLoggerConfig
	conf.Format = "${time_rfc3339} ${remote_ip} ${method} ${status} ${uri}\n"
	logger := middleware.LoggerWithConfig(conf)
	eng.Use(logger)
	eng.Use(middleware.Recover())

	//static files
	eng.Static("/assets", "./public")
	eng.File("/favicon.ico", "./public/favicon.ico")

	//template
	eng.SetRenderer(newTemplate("templates/**/*.html"))

	//session
	store := session.NewCookieStore([]byte(SessSecret))
	eng.Use(session.Sessions(SessName, store))

	//router
	routing(eng)

	return eng
}

func routing(eng *echo.Echo) {
	eng.GET("/proxy/:source/*", handle.Proxy)
	auth := jmauth.NewJMAuth().Process
	eng.GET("/", handle.Index, auth) //jump to admin
	eng.POST("/api/syncpriv", api.SyncPrivAPI)
	g := eng.Group("/admin", auth)
	{
		g.GET("/index", handle.Admin)
		g.GET("/logout", handle.Logout)

		g.GET("/setting/index", setting.Index)
		g.GET("/setting/new", setting.New)
		g.GET("/setting/edit/:key", setting.Edit)
		g.GET("/setting/consul", setting.Consul)

		g.POST("/setting/new", setting.New)
		g.POST("/setting/edit/:key", setting.Edit)
		g.POST("/setting/delete/:key", setting.Delete)

		g.GET("/logs/slowquery", logs.SlowQuery)
		g.GET("/logs/errorlog", logs.ErrorLog)

		g.GET("/stats/:dashboard", stats.Grafana)

		g.GET("/api/index", api.Index)
		g.GET("/api/syncpriv", api.SyncPriv)
		g.POST("/api/syncpriv", api.SyncPriv)
		g.POST("/api/switchdc", api.SwitchDC)

	}
}
